package game.sb;

import com.bit.catmoney.CFxSound;
import com.bit.catmoney.R;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import common.AudioClip;
import common.Tools;

public class CatMoneyGame extends ArcadeGame {
	// 게임 이름
	public static final String NAME = "SpaceBlaster";

	// 갱신 주기
	private static final long UPDATE_DELAY = 40;
	public static int RUN = 1;
	public static int PAUSE = 2;

	public static int mMode = RUN;

	private Context mContext;

	// 텍스트용
	// 텍스트의 스타일과 색상을 담은 Paint 객체
	private Paint mTextPaint = new Paint();

	// 비트맵용
	// 모든 비트맵에 적용되는 스타일과 색상 정보를 담는 Paint 객체
	private Paint mBitmapPaint = new Paint();
	// 화면 하단의 레이저 동력 막대를 위한 스타일과 색상 정보를 담는 Paint 객체
	// private Paint mLaserBarPaint = new Paint();
	// // 화면 하단의 보호막 동력 막대를 위한 스타일과 색상 정보를 담는 Paint 객체
	private Paint mShieldBarPaint = new Paint();
	// // 우주선 보호막 이미지를 위한 스타일과 색상 정보를 담는 Paint 객체
	// private Paint mShieldPaint = new Paint();
	int i = 2;
	public Canvas goff2;
	public int img_type_money500 = 0;
	public int img_type_money1000 = 0;

	float x1, y1, x2, y2;

	/**
	 * Constructor
	 * 
	 * @param context
	 */
	// 생성자
	public CatMoneyGame(Context context) {
		super(context);
		mContext = context;
		super.setUpdatePeriod(UPDATE_DELAY);
	}

	public CatMoneyGame(Context context, AttributeSet attrs) {
		super(context, attrs);
		mContext = context;
		super.setUpdatePeriod(UPDATE_DELAY);
	}

	// 안드로이드 키 사건 처리
	// @Override
	// public boolean onKeyUp(int keyCode, KeyEvent event) {
	// keyUp(keyCode); // event,
	// return true;
	// }
	//
	// @Override
	// public boolean onKeyDown(int keyCode, KeyEvent event) {
	// // keyDown(keyCode); // event,
	// return true;
	// }

	/**
	 * Main Draw Sub
	 */
	@Override
	protected void onDraw(Canvas canvas) {
		super.dispatchDraw(canvas);
		paint(canvas);

	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if(mMode == PAUSE) return false;
		if (event.getAction() == MotionEvent.ACTION_MOVE) {
			x1 = event.getX();
			y1 = event.getY();
			if (x1 > getWidth() / 2 && x1 < getWidth() && y1 > getHeight() / 4
					&& y1 < getHeight()) {
				x += 10;
				i = 0;
				invalidate();
			}
			if (x1 > 10 && x1 < getWidth() / 2 && y1 > getHeight() / 4
					&& y1 < getHeight()) {
				x -= 10;
				i = 1;
				invalidate();
			}
		} else if (event.getAction() == MotionEvent.ACTION_UP) {
			i = 2;
			x2 = event.getX();
			y2 = event.getY();
			if (!ingame) {
				// 게임이 아직 시작되지 않았다면 지금 시작한다.
				ingame = true;
				GameStart();
			}
		}
		return true;
	}

	/*************************************************************
	 * GAME Code
	 ************************************************************/
	boolean ingame = false;
	int x, y, mousex, mousey, oldx, oldy, dx = 0, dy = 0, count, shield = 0;
	boolean showtitle = true;
	Bitmap charater1 = BitmapFactory.decodeResource(getResources(),
			R.drawable.basic11);
	Bitmap charater2[] = new Bitmap[2];
	Bitmap charater3[] = new Bitmap[2];

	// Bullet variables
	Bitmap bullet;
	int[] bx;
	int[] by;
	int cw, ch;
	final int bmy = 16, bul_xs = 54, bul_ys = 8;
	int counter = 0;
	int Won;
	String s;
	int m;

	// 게임 시작 멘트
	public String ss;

	// Meteor variables
	Bitmap meteor1[] = new Bitmap[10];
	Bitmap meteor500[] = new Bitmap[3];
	Bitmap thunder = BitmapFactory.decodeResource(getResources(),
			R.drawable.thunder);
	int maxmoney, metcount, mtotal, mrenew, metmy;
	int[] monx;
	int[] mony;
	int[] monf;
	boolean[] monr;
	final int sxmet = 90, symet = 20;

	// These are for the star field
	public int starsX[];
	public int starsY[];
	public Paint starsC[];
	public int numStars = 400;
	public int speed = 8, xSize, ySize;

	// Variables for big boom
	// Bitmap[] boom;
	// int rndbx, rndby, rndcnt = 77
	// final int sxbom = 71, sybom = 100, bframes = 4;

	// Global Variables
	int distance = 0, maxdist = 2000;
	int slevel, blevel, difflev, bosslevel;
	int smax, bmax;
	int scur, bcur, renew, rcnt = 0, sstretch, txtalign = 100;
	long score;

	// Sounds
	AudioClip blast, crash, kill;

	// Game Stuff
	final int maxshield = 9;
	final int backcol = 0x102040;
	final int borderwidth = 0;
	final int sxsize = 40, sysize = 200;
	final int movex = 10, movey = 5;
	final int scoreheight = 45;
	final int screendelay = 300;

	private int countMoneyAny;

	// private int countMoneyAny = 200;

	// 게임 초기화
	// 화면 크기를 설정한다.
	// 텍스트,레이저 동력 막대,보호막 동력 막대를 위한 Paint 객체들의 스타일과 색상을 결정.
	// 게임 비트맵 스프라이트들(우주선,운석,레이저 탄환,폭발 애니메이션 시퀀스)을 적재한다.
	// 효과음용 음향 클립들을 적재한다.
	public void initialize() {
		int n;

		// 화면 크기
		int width = getWidth();
		int height = getHeight();

		// 텍스트용 Paint
		mTextPaint.setARGB(255, 255, 255, 255);
		// mShieldPaint.setARGB(125, 0, 255, 255);

		// 보호막 동력 막대용 Paint
		mShieldBarPaint.setARGB(255, 255, 0, 0);
		mShieldBarPaint.setStyle(Paint.Style.FILL);

		// 도둑고양이
		charater2[0] = BitmapFactory.decodeResource(getResources(),
				R.drawable.basic21);
		charater2[1] = BitmapFactory.decodeResource(getResources(),
				R.drawable.basic31);
		charater3[0] = BitmapFactory.decodeResource(getResources(),
				R.drawable.basic41);
		charater3[1] = BitmapFactory.decodeResource(getResources(),
				R.drawable.basic51);

		xSize = width;
		ySize = height;

		x = (xSize - sxsize) / 2;
		y = 0;
		mousex = -1;

		blevel = 3;
		slevel = 3;

		bx = new int[blevel * 10];
		by = new int[blevel * 10];

		for (n = 0; n < blevel * 10; n++) {
			bx[n] = -1;
		}

		// 동전 초기화
		// meteor = getImage(R.drawable.money500);
		
		meteor1[0] = BitmapFactory.decodeResource(getResources(),
				R.drawable.fish);
		meteor1[1] = BitmapFactory.decodeResource(getResources(),
				R.drawable.money10);
		meteor1[2] = BitmapFactory.decodeResource(getResources(),
				R.drawable.money_500);
		meteor1[3] = BitmapFactory.decodeResource(getResources(),
				R.drawable.money);
		meteor1[4] = BitmapFactory.decodeResource(getResources(),
				R.drawable.money_1000);
		meteor1[5] = BitmapFactory.decodeResource(getResources(),
				R.drawable.money_1000);
		meteor1[6] = BitmapFactory.decodeResource(getResources(),
				R.drawable.money10);
		meteor1[7] = BitmapFactory.decodeResource(getResources(),
				R.drawable.fish);
		meteor1[8] = BitmapFactory.decodeResource(getResources(),
				R.drawable.fish);
		meteor1[9] = BitmapFactory.decodeResource(getResources(),
				R.drawable.money);

		meteor500[0] = BitmapFactory.decodeResource(getResources(),
				R.drawable.money_500);
		meteor500[1] = BitmapFactory.decodeResource(getResources(),
				R.drawable.money_500_1);
		meteor500[2] = BitmapFactory.decodeResource(getResources(),
				R.drawable.money_500_2);

		maxmoney = height / symet + 1;
		maxmoney = maxmoney * 10;
		monx = new int[maxmoney];
		mony = new int[maxmoney];
		monf = new int[maxmoney];
		monr = new boolean[maxmoney];

		// 음향 클립들을 적재한다.
		try {
			// 동전과 충돌
			crash = getAudioClip(R.raw.coin);
		} catch (Exception e) {
			Tools.MessageBox(mContext, "Audio Error: " + e.toString());
		}

		initStars();

	}

	/**
	 * create the starfield in the background
	 */
	public void initStars() {
		starsX = new int[numStars];
		starsY = new int[numStars];
		starsC = new Paint[numStars];
		for (int i = 0; i < numStars; i++) {
			starsX[i] = (int) ((Math.random() * xSize - 1) + 1);
			starsY[i] = (int) ((Math.random() * ySize - 1) + 1);
			starsC[i] = newColor();
		}
	}

	/**
	 * Process key down event
	 * 
	 * @param key
	 *            Android Key code
	 * @return
	 */

	// 키 눌림사건을 처리
	//
	// public boolean keyDown(int key) {
	// if (ingame) {
	// mousex = -1;
	// if (key == KeyEvent.KEYCODE_DPAD_LEFT || key == KeyEvent.KEYCODE_Q)
	// dx = -1;
	// if (key == KeyEvent.KEYCODE_DPAD_RIGHT || key == KeyEvent.KEYCODE_W)
	// dx = 1;
	// if (key == KeyEvent.KEYCODE_DPAD_UP || key == KeyEvent.KEYCODE_O)
	// dy = -1;
	// if (key == KeyEvent.KEYCODE_DPAD_DOWN || key == KeyEvent.KEYCODE_L)
	// dy = 1;
	// if ((key == KeyEvent.KEYCODE_SPACE) || (key == 23)) {
	// if (bcur > 0) {
	// fireGun();
	// }
	// }
	// } else {
	// if (key == KeyEvent.KEYCODE_S) {
	// ingame = true;
	// GameStart();
	// }
	// }
	// if (key == KeyEvent.KEYCODE_E) {
	// ingame = false;
	// // stopUpdateTimer();
	// }
	//
	// if (key == KeyEvent.KEYCODE_Q) {
	// // 전혀 마음에 들지 않는 게임 종료 방법.
	// System.exit(0);
	// }
	// return true;
	// }

	/**
	 * Process key up event
	 * 
	 * @param e
	 *            Key event
	 * @param key
	 *            key code
	 * @return
	 */
	// 키가 떼어졌을때 사건을 처리한다.
	// public boolean keyUp(int key) { // KeyEvent e,
	// if (key == KeyEvent.KEYCODE_DPAD_LEFT
	// || key == KeyEvent.KEYCODE_DPAD_RIGHT
	// || key == KeyEvent.KEYCODE_Q || key == KeyEvent.KEYCODE_W)
	// dx = 0;
	// if (key == KeyEvent.KEYCODE_DPAD_UP
	// || key == KeyEvent.KEYCODE_DPAD_DOWN
	// || key == KeyEvent.KEYCODE_O || key == KeyEvent.KEYCODE_L)
	// dy = 0;
	// return true;
	// }

	// 시작하면 playGame을 호출해서 그려주는 메서드
	// 시작하지 않으면 showIntroScreen()호출해서 그려주는 메서드
	public void paint(Canvas g) {
		
		if (ingame) {
			playGame(g);
		} else {
			showIntroScreen(g);
		}
	}

	// 게임중 그려주는 메서드
	public void playGame(Canvas c) {
		newMeteor();
		moveCat();
		drawPlayField(c);

		showScore(c);
		distance++;
		// score += 100;

		if (distance % maxdist == 0) {
			difflev++;
			if (difflev > 2 & difflev < 10) {
				renew -= 20;
				bmax += 1;
				smax += 1;
				metmy++;
				mrenew--;
			}
			// if (difflev > 3 & difflev < 11) {
			// maxtribe++;
			// sbmove++;
			// }
			// if (difflev > 3) {
			// sunbird = true;
			// tribe = maxtribe;
			// }
		}

		// Renew Ship Energy
		// rcnt++;
		// if (rcnt % (renew / blevel) == 0) {
		// bcur++;
		// if (bcur > bmax)
		// bcur = bmax;
		// }
		// if (distance % 500 == 0) {
		// scur++;
		// if (scur > smax)
		// scur = smax;
		// }
		// if (rcnt > renew)
		// rcnt = 0;
	}

	// 게임 초기화면그려주는 메서드
	public void showIntroScreen(Canvas canvas) {
		String s;
		int width = getWidth();
		int height = getHeight();

		drawPlayField(canvas);
		s = "Game GoGo!";
		canvas.drawText(s,
				(width - (s.length() * mTextPaint.getTextSize() / 2)) / 2,
				(height - scoreheight - borderwidth) / 2 - 20, mTextPaint);
		mTextPaint.setTextSize(60);
		count--;
		if (count <= 0) {
			count = screendelay;
			showtitle = !showtitle;
		}
	}

	// 배경그려주는 메서드
	public void drawPlayField(Canvas canvas) {
		// Show stars
		
		moveStars();
		for (int a = 0; a < numStars; a++) {
			// canvas.setColor(starsC[a]);
			// Draw starts
			canvas.drawRect(starsX[a], starsY[a], starsX[a] + 2, starsY[a] + 2,
					starsC[a]);
		}
		showMeteors(canvas);
		// KillEmAll(canvas);
		counter++;
		int n = counter % 20 / 10;
		if (i == 1) {
			canvas.drawBitmap(charater2[n], x, y, mBitmapPaint);
		} else if (i == 0) {
			canvas.drawBitmap(charater3[n], x, y, mBitmapPaint);
		} else if (i == 2) {
			canvas.drawBitmap(charater1, x, y, mBitmapPaint);
		} // paint ship

		canvas.drawBitmap(thunder, 0, 0, mBitmapPaint);

		processCollisions();

		if (shield > 0) {
			shield--;
		}
	}

	/**
	 * Show the laser shield and score values in the lower part of the screen
	 * 
	 * @param goff
	 */
	// Score보여주는 메서드
	public void showScore(Canvas goff) {
		int my;
		int height = getHeight();

		sstretch = (xSize - txtalign * 2) / Math.max(bmax, smax);

		my = height - scoreheight;
		// goff.drawRect(txtalign, my - 10, txtalign + bmax * sstretch, my,
		// mTextPaint);

		// Shield bar
		my += 15;
		// goff.drawRect(txtalign, my - 10, txtalign + smax * sstretch, my,
		// mTextPaint);

		// Fill rect
		s = "에너지: " + scur + "/" + smax;
		goff.drawRect(txtalign + 200, my - 70, txtalign + scur * sstretch,
				my - 50, mShieldBarPaint);
		goff.drawText(s, 10, my - 40, mTextPaint);
		mTextPaint.setTextSize(60);

		// Score
		my += 20;

		s = "총 적립금: " + score;
		goff.drawText(s, 10, my, mTextPaint);

	}

	public void moveCat() {
		if(mMode == PAUSE) return;
		int width = getWidth();
		int height = getHeight();
		cw = (charater1.getWidth() / 2);
		ch = 105;
		oldx = x;
		oldy = y;

		if (m == 1) {
			y -= metmy + 10;
			m = 0;
		} else if (m == 2) {
			y += meteor1[2].getHeight() + 80;
			m = 0;
		} else if (m == 3) {
			x -= 100;
			m = 0;
		} else {
			y += 7;
		}

		if (x < cw) {// 왼쪽 벽
			x = cw;
		} else if (x > width - ch) {// 오른쪽벽
			x = width - ch;
		} else if (y < 0) { // 천정
			y = 10;
			scur--;
		} else if (y >= height) {
			GameOver();
			y = 100;
		}
	}

	// 운석 그려주는 메서드
	public void showMeteors(Canvas goff) {
		if(mMode == PAUSE) return;
		int n;
		goff2 = goff;
		mtotal = 0;
		for (n = 0; n < maxmoney; n++) {
			if (monx[n] >= 0) {
				mtotal++;
				mony[n] -= metmy + 10;
				// if (mety[n] > height - borderwidth - scoreheight) {
				if (mony[n] <= -25) {
					deleteMeteor(n);
				} else {
					if (monr[n]) {
						if (oldmon2 == n) {
							switch (img_type_money500) {
							case 0:
								goff.drawBitmap(meteor500[0], monx[n], mony[n],
										mBitmapPaint);
								break;
							case 1:
								goff.drawBitmap(meteor500[1], monx[n], mony[n],
										mBitmapPaint);
								break;
							case 2:
								goff.drawBitmap(meteor500[2], monx[n], mony[n],
										mBitmapPaint);
								break;
							}
						} else {
							goff.drawBitmap(meteor1[n], monx[n], mony[n],
									mBitmapPaint);
						}
						// meteor
					} else {
						monf[n]--;
						if (monf[n] < 0)
							deleteMeteor(n);
					}
				}
			}
		}
	}

	public void newMeteor() {
		if(mMode == PAUSE) return;
		int height = getHeight();
		int n = 0, f = -1;
		metcount++;
		if (metcount > mrenew / metmy) {
			metcount = 0;
			while (n < maxmoney & monx[n] >= 0)
				n++;
			if (n < maxmoney)
				f = n;
			if (f >= 0) {
				monx[f] = (int) (Math.random() * (xSize - sxmet) + 1);
				mony[f] = height;
				monr[f] = true;
			}
		}
	}

	// If a star in the background reaches the bottom then it will go back to
	// the top
	public void moveStars() {
		if(mMode == PAUSE) return;
		for (int i = 0; i < numStars; i++) {
			// if (starsY[i] + 1 > ySize - (speed * 2)) {
			if (starsY[i] + 1 < 0) {
				starsY[i] = getHeight();
				starsX[i] = (int) ((Math.random() * xSize - 1) + 1);
				starsC[i] = newColor();
			} else {
				starsY[i] -= speed;
			}
		}
	}

	public void processCollisions() {

		for (int n = 0; n < maxmoney; n++) {
			if (monx[n] >= 0) {
				if (monr[n] & x + sxsize > monx[n] & x < monx[n] + sxmet
						& y + sysize > mony[n] & y < mony[n] + symet) {
					m = 1;
					if (isCrash == false) {
						oldmon = n;
						hitCat(n);
						if (n == 2) {
							oldmon2 = n;
							t t = new t();
							t.start();
						}
						else if(n == 4){
							m=3;
						}
					}
					// deleteMeteor(n);
				} else if (oldmon == n) {
					isCrash = false;
				}
			}
		}
	}

	public class t extends Thread {
		@Override
		public void run() {
			// TODO Auto-generated method stub
			try {
				sleep(700);
				img_type_money500 = 1;
				sleep(200);
				img_type_money500 = 2;
				m = 2;
				sleep(200);
				img_type_money500 = 0;
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	public int oldmon = 1000;
	public int oldmon2 = 1000;
	public boolean isCrash = false;

	public void hitCat(int n) {
		 if (CFxSound.getIsPlay()) {
		 crash.play();
		 }
		// Won=1;
		isCrash = true;
		// if(meteor1[2]&&meteor1[3]){
		switch (n) {
		case 0:
			scur--;
			break;
		case 1:
			score += 10;
			break;
		case 2:
			score += 500;
			break;
		case 3:
			score += 100;
			break;
		case 4:
			score += 1000;
			break;
		case 5:
			score += 1000;
			break;
		case 6:
			score += 10;
			break;
		case 7:
			scur--;
			break;
		case 8:
			scur--;
			break;
		case 9:
			score += 100;
			break;
		}
		// score += 100;
		// }

		shield = maxshield;

		if (scur < 0)
			GameOver();
	}

	public void deleteMeteor(int n) {
		if (monr[n]) {
			monr[n] = false;
			// metf[n] = bframes;
		} else {
			monx[n] = -1;
			monr[n] = true;
			monf[n] = 0;
		}
	}

	public Paint newColor() {
		int[] rgb;
		int t;
		rgb = new int[3];
		for (int i = 0; i < 3; i++)
			rgb[i] = 180;
		t = (int) (Math.random() * 3);
		rgb[t] = (int) (Math.random() * 128 + 1) + 127;
		Paint p = new Paint();
		p.setARGB(255, rgb[0], rgb[1], rgb[2]);
		return p;
	}

	// Game Start
	public void GameStart() {
		// Set Up Ship variables
		smax = slevel * slevel;
		scur = smax;
		// difflev = 3;
		distance = 0;
		score = 0;
		renew = 250;
		for (int n = 0; n < maxmoney; n++) {
			monx[n] = -1;
			monf[n] = 0;
			monr[n] = true;
		}
		metcount = 0;
		metmy = 2;
		mrenew = 60;
	}

	public interface OnGameOverListener {
		void onGameOvered(View sender, long score);
	}

	public void setOnGameOverListener(OnGameOverListener listener) {
		onGameOvered = listener;
	}

	OnGameOverListener onGameOvered = null;

	// Game Over
	public void GameOver() {
		ingame = false;
		if (onGameOvered != null) {
			onGameOvered.onGameOvered(this, getScore());
		}
	}

	@Override
	protected void updatePhysics() {
	}

	@Override
	protected boolean gameOver() {
		return ingame;

	}

	@Override
	protected long getScore() {
		return score;
	}
}
